package com.lagou.edu.handler;

import com.lagou.edu.context.stereotype.Transactional;
import com.lagou.edu.utils.TransactionManager;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @Author zhaozuowen
 * @Description
 * @Date 2020/1/7 21:30
 **/

public class TransactionInvocationHandler implements InvocationHandler {

    private TransactionManager transactionManager;
    private Object targetObject;
    public TransactionInvocationHandler() {
    }

    public TransactionInvocationHandler(TransactionManager transactionManager,Object targetObject) {
        this.transactionManager=transactionManager;
        this.targetObject=targetObject;

    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;

        //判断方法是否有@Transaction注解，如果有则进行事务控制
        //TODO这里获取的是接口方法，如果获取实现类的方法注解
        Class<?>[] parameterTypes=method.getParameterTypes();
        Method declaredMethod = targetObject.getClass().getDeclaredMethod(method.getName(), parameterTypes);
        Transactional annotation = declaredMethod.getDeclaredAnnotation(Transactional.class);
        if(annotation!=null){
            try{
                // 开启事务(关闭事务的自动提交)
                transactionManager.beginTransaction();
                result = method.invoke(targetObject,args);
                // 提交事务
                transactionManager.commit();
            }catch (Exception e) {
                e.printStackTrace();
                // 回滚事务
                transactionManager.rollback();

                // 抛出异常便于上层servlet捕获
                throw e;
            }
        }else {
            result = method.invoke(targetObject,args);
        }

        return result;
    }
}
